<template>
  <div class="vue-flow-node" :class="selected ? 'selected' : ''">
    <!-- 流程节点 -->
    <div class="vue-flow-node-body process" v-if="type === 'process'">
      <div
        class="vue-flow-node-title"
        v-show="!isEditing"
        @contextmenu="handleRightClick"
      >
        <span>{{ name }}</span>
      </div>
      <input
        type="text"
        class="vue-flow-node-change-name-input"
        ref="nameInput"
        v-if="isEditing"
        :value="name"
        @blur="handleNameChange"
        @keyup.enter="handleNameChange"
      />
    </div>
    <!-- 判定节点 -->
    <div class="vue-flow-node-body decision" v-else-if="type === 'decision'">
      <div class="diamond"></div>
      <div
        class="vue-flow-node-title"
        v-show="!isEditing"
        @contextmenu="handleRightClick"
      >
        <span>{{ name }}</span>
      </div>
      <input
        type="text"
        class="vue-flow-node-change-name-input"
        ref="nameInput"
        v-if="isEditing"
        :value="name"
        @blur="handleNameChange"
        @keyup.enter="handleNameChange"
      />
    </div>
    <!-- 开始/结束 节点 -->
    <div
      class="vue-flow-node-body termination"
      v-else-if="type === 'termination'"
    >
      <div
        class="vue-flow-node-title"
        v-show="!isEditing"
        @contextmenu="handleRightClick"
      >
        <span>{{ name }}</span>
      </div>
      <input
        type="text"
        class="vue-flow-node-change-name-input"
        ref="nameInput"
        v-if="isEditing"
        :value="name"
        @blur="handleNameChange"
        @keyup.enter="handleNameChange"
      />
    </div>
    <!-- 数据节点 -->
    <div class="vue-flow-node-body data" v-else-if="type === 'data'">
      <div
        class="vue-flow-node-title"
        v-show="!isEditing"
        @contextmenu="handleRightClick"
      >
        <span>{{ name }}</span>
      </div>
      <input
        type="text"
        class="vue-flow-node-change-name-input"
        ref="nameInput"
        v-if="isEditing"
        :value="name"
        @blur="handleNameChange"
        @keyup.enter="handleNameChange"
      />
    </div>
    <!-- 子流程节点 -->
    <div
      class="vue-flow-node-body subprocess"
      v-else-if="type === 'subprocess'"
    >
      <div
        class="vue-flow-node-title"
        v-show="!isEditing"
        @contextmenu="handleRightClick"
      >
        <span>{{ name }}</span>
      </div>
      <input
        type="text"
        class="vue-flow-node-change-name-input"
        ref="nameInput"
        v-if="isEditing"
        :value="name"
        @blur="handleNameChange"
        @keyup.enter="handleNameChange"
      />
    </div>
  </div>
</template>

<script>
import EventBus from "../../../event-bus/index";
import BusEvents from "../../../event-bus/event-types";

export default {
  name: "vue-flow-node",
  inject: ["getGraph", "getNode"],
  data() {
    return {
      isEditing: false,
      nodeData: this.getNode().getData(),
      name: this.getNode().getData().name,
      type: this.getNode().getData().type.split(".")[1] || "process",
      /**
       * 流程 --> process
       * 判定 --> decision
       * 开始/结束 --> termination
       * 数据 --> data
       * 子流程 --> subprocess
       */
    };
  },
  computed: {
    selected() {
      return this.nodeData.selected;
    },
  },
  methods: {
    handleRightClick() {
      this.isEditing = true;
      this.$nextTick(() => {
        const oInput = this.$refs.nameInput;
        oInput.focus();
        oInput.select();
      });
    },
    handleNameChange() {
      this.isEditing = false;
      const newVal = this.$refs.nameInput.value;
      if (this.name !== newVal) {
        this.name = newVal;
        this.getNode().getData().name = newVal;
        // todo: 更新 id2nameMap 上的名字
        const id = this.getNode().id;
        EventBus.$emit(BusEvents.INTERACT_UPDATE_ID2NAME_MAP, {
          id,
          name: newVal,
        });
      }
    },
  },
};
</script>

<style lang="less">
.vue-flow-node {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  border: 2px solid transparent;
  display: flex;
  justify-content: center;
  // overflow: hidden;

  &.selected {
    border-color: orange;
  }

  .vue-flow-node-body {
    width: 100%;
    height: 100%;

    display: flex;
    justify-content: center;
    align-items: center;

    &.process {
      background-color: #63abf7;
    }

    &.decision {
      position: relative;

      // 菱形背景
      .diamond {
        /* 向左的三角形 */
        width: 0;
        height: 0;
        box-sizing: border-box;
        border: 98px solid #63abf7;
        border-top-width: 38px;
        border-bottom-width: 38px;
        border-left-color: transparent;
        border-top-color: transparent;
        border-bottom-color: transparent;
        position: absolute;
        left: -98px;
        z-index: -1;

        display: flex;
        justify-content: center;
        align-items: center;

        &::after {
          content: "";
          position: absolute;
          box-sizing: border-box;
          border: 98px solid #63abf7;
          border-top-width: 38px;
          border-bottom-width: 38px;
          border-right-color: transparent;
          border-top-color: transparent;
          border-bottom-color: transparent;
          left: 98px;
          z-index: -1;
        }
      }
    }

    &.termination {
      border-radius: 40px;
      background-color: #63abf7;
    }

    &.data {
      width: 80%;
      background-color: #63abf7;
      transform: skewX(-20deg);

      & > * {
        transform: skewX(20deg);
      }
    }

    &.subprocess {
      position: relative;
      background-color: #63abf7;

      &::before {
        content: "";
        position: absolute;
        width: 6px;
        height: 100%;
        left: 20px;
        background-color: #fff;
      }

      &::after {
        content: "";
        position: absolute;
        width: 6px;
        height: 100%;
        right: 20px;
        background-color: #fff;
      }
    }

    .vue-flow-node-title {
      height: 24px;
      width: 60%;
      color: white;
      text-align: center;
    }

    .vue-flow-node-change-name-input {
      height: 24px;
      width: 60%;
      border: 1px solid #dcdfe6;
      border-radius: 2px;
      outline: none; /* 修改原有的边框样式 */

      &:focus,
      &:focus-visible {
        // border: 1px solid #409eff;
        border: 1px solid #98afc7;
        border-radius: 2px;
      }
    }
  }
}
</style>
